package ge.gen.eBdgt.action;

import ge.gen.eBdgt.action.graph.IcnDataset;
import ge.gen.eBdgt.service.IcnService;
import ge.gen.eBdgt.utils.ProjUtils;
import ge.gen.eBdgt.vo.OutageMonthVO;
import ge.gen.eBdgt.vo.ProjectKindVO;
import ge.gen.eBdgt.vo.TeamWrkLoadVO;

import java.awt.Color;
import java.io.File;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.CategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.urls.CategoryURLGenerator;
import org.jfree.data.category.CategoryDataset;

public class IcnTeamWrkLdGraphAction extends BaseAction {
	public String imagesPath;
	private List<TeamWrkLoadVO> teamWrkLoad;
	String currentPath;
	String fileName;
	private List<OutageMonthVO> outagesByMonth;
	private String graphType;
	private String graphOptions;
	private String title;
	private String domainAxisLbl;
	private String rngeAxisLbl;
	int maxYNum = 0;
	int maxXNum = 0;
	private int width;
	private int height;
	private List<ProjectKindVO> projectKind;
	List<String> monthsList;
	private List<String> yearList;
	private String yearSelected;
	String selectYear;
	String selectMonth;

	public IcnTeamWrkLdGraphAction() throws Exception {
		super();
	}

	public class MyGenerator implements CategoryURLGenerator,
			CategoryToolTipGenerator, CategoryItemLabelGenerator {
		private String prefix = "index.html";
		IcnService icnService;

		public MyGenerator(String prefix, IcnService icnService) {
			this.prefix = prefix;
			this.icnService = icnService;
		}

		public String myGenerateURL(Comparable seriesKey, Comparable categoryKey) {
			return request.getContextPath() + prefix + seriesKey.toString();
		}

		public String myGenerateToolTip(Comparable seriesKey) {
			String sNo = icnService.getSerialNo(seriesKey.toString());
			return "\tICN: " + seriesKey.toString() + "\n  SERIAL NO: " + sNo;
		}

		public String generateURL(CategoryDataset dataset, int series,
				int category) {
			return myGenerateURL(dataset.getRowKey(series), dataset
					.getColumnKey(category));
		}

		public String generateToolTip(CategoryDataset dataset, int series,
				int category) {
			return myGenerateToolTip(dataset.getRowKey(series));
		}

		@Override
		public String generateColumnLabel(CategoryDataset dataset, int series) {
			return "test1";
		}

		@Override
		public String generateLabel(CategoryDataset dataset, int series,
				int category) {
			return (String) dataset.getRowKey(series);
		}

		@Override
		public String generateRowLabel(CategoryDataset dataset, int series) {
			return "test3";
		}
	}

	public JFreeChart createChart(final IcnDataset dataset,
			IcnService icnService) {
		final JFreeChart chart = ChartFactory.createStackedBarChart(title,
				domainAxisLbl, rngeAxisLbl, dataset, PlotOrientation.VERTICAL,
				false, true, false);
		chart.setBackgroundPaint(new Color(249, 231, 236));
		CategoryPlot plot = chart.getCategoryPlot();
		NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		plot.getRenderer().setSeriesPaint(0, new Color(128, 0, 0));
		plot.getRenderer().setSeriesPaint(1, new Color(0, 0, 255));
		plot.getRangeAxis().setRange(0, maxYNum + 1);
		CategoryItemRenderer renderer = plot.getRenderer();
		MyGenerator generator = new MyGenerator("/detail.action?icn=",
				icnService);
		renderer.setBaseItemURLGenerator(generator);
		renderer.setBaseToolTipGenerator(generator);
		renderer.setItemLabelGenerator(generator);
		renderer.setBaseItemLabelsVisible(true);
		return chart;
	}

	private IcnDataset createDataset(List list) {
		String prev = "";
		int j, k;
		Comparable[] rowKeys = new Comparable[list.size()];
		Comparable[] columnKeys = new Comparable[list.size()];
		IcnDataset dataset = new IcnDataset();
		double[][] data = new double[list.size()][list.size()];
		j = -1;
		k = 0;
		for (int i = 0; i < list.size(); i++) {
			String vo = (String) list.get(i);
			String s[] = vo.split("\\s");
			if (s != null && s.length >= 2) {
				if (prev.equals(s[0]) == false) {
					j++;
					k = 0;
					rowKeys[j] = s[0];
					columnKeys[j] = "" + i;
				}
				dataset.addValue(1, s[1], s[0]);
				dataset.insertIcn(s[1]);
				data[j][k] = 1;
				prev = s[0];
				k++;
			}
		}
		return dataset;
	}

	private ArrayList createTeamWorkLoadData() {
		int num = 0;
		String prevEng = "";
		ArrayList list = new ArrayList();
		setGraphParameters("graphTeamWorkLoad.png", "Team Work Load",
				"REQ ENGR", "No of Icns", 1400, 500);
		teamWrkLoad = icnService.getTeamWrkLoad();
		Iterator<TeamWrkLoadVO> iter = teamWrkLoad.iterator();
		for (int i = 0; i < teamWrkLoad.size(); i++) {
			TeamWrkLoadVO vo = teamWrkLoad.get(i);
			if (vo != null && isBlank(vo.getReqEng()) == false) {
				String eng = vo.getReqEng().replaceAll(" ", "_");
				list.add(eng + " " + vo.getIcn());
				num++;
				if (prevEng.equals(eng) == false) {
					if (maxYNum < num) {
						maxYNum = num;
					}
					num = 0;
				}
				prevEng = eng;
			}
		}
		return list;
	}

	private ArrayList createOutageMonthData(int yr, int mn) throws Exception {
		int num = 0;
		String prevEng = "";
		ArrayList list = new ArrayList();
		outagesByMonth = icnService.getOutagesMonth(mn, yr);
		Iterator<OutageMonthVO> iter = outagesByMonth.iterator();
		for (int i = 0; i < outagesByMonth.size(); i++) {
			OutageMonthVO vo = outagesByMonth.get(i);
			if (vo != null && vo.getOutageDate() >= 0) {
				String eng = getMonth(vo.getOutageDate());
				list.add(eng + " " + vo.getIcn());
				num++;
				if (prevEng.equals(eng) == false) {
					if (maxYNum < num) {
						maxYNum = num;
					}
					num = 0;
				}
				prevEng = eng;
			}
		}
		String outage = getOutageString(mn, yr);
		setGraphParameters("graphOutageMonth - " + yr + ".png", outage,
				"MONTH", "No of Icns", 1000, 400);
		return list;
	}

	private ArrayList createProjectKindData(String yr) {
		int num = 0;
		String prevEng = "";
		ArrayList list = new ArrayList();
		setGraphParameters("graphProjectKind.png", "Kind Of Projects"
				+ yearSelected, "MAIN SCOPE", "No of Icns", 2000, 450);
		projectKind = icnService.getProjectsByKind(yr);
		Iterator<ProjectKindVO> iter = projectKind.iterator();
		for (int i = 0; i < projectKind.size(); i++) {
			ProjectKindVO vo = projectKind.get(i);
			if (vo != null && isBlank(vo.getProjectKind()) == false) {
				String eng = vo.getProjectKind().replaceAll(" ", "_");
				list.add(eng + " " + vo.getIcn());
				num++;
				if (prevEng.equals(eng) == false) {
					if (maxYNum < num) {
						maxYNum = num;
					}
					maxXNum++;
					num = 0;
				}
				prevEng = eng;
			}
		}
		return list;
	}

	private void setGraphParameters(String fname, String title,
			String domainAxisLbl, String rngeAxisLbl, int width, int height) {
		this.fileName = fname;
		this.title = title;
		this.domainAxisLbl = domainAxisLbl;
		this.rngeAxisLbl = rngeAxisLbl;
		this.width = width;
		this.height = height;
	}

	public String getMonth(int month) {
		month = (month >= 12) ? (month - 12) : month;
		return new DateFormatSymbols().getMonths()[month];
	}

	private String getOutageString(int mn, int yr) {
		int monthYearEnd[] = ProjUtils.addMonths(mn, yr);
		String s = "Outages  (" + new DateFormatSymbols().getMonths()[mn] + "'"
				+ yr;
		if (monthYearEnd.length > 0)
			s = s + "  -  "
					+ new DateFormatSymbols().getMonths()[monthYearEnd[0]]
					+ "'" + monthYearEnd[1];
		s = s + ")";
		return s;
	}

	public String createGraph() throws Exception {
		try {
			IcnDataset dataset = null;
			session = request.getSession();
			graphType = (String) request.getParameter("graphType");
			yearList = icnService.getAllYears();
			graphOptions = "0";
			if (graphType.equals("1")) {
				teamWrkLoad = createTeamWorkLoadData();
				dataset = createDataset(teamWrkLoad);
			} else if (graphType.equals("2")) {
				int year = -10, mn = -10;
				graphOptions = "1";
				if (isNotNull(selectYear))
					year = Integer.parseInt(selectYear);
				mn = getMonth(selectMonth);
				if (mn < 0) {
					year = 2011;
					mn = 0;
				}
				outagesByMonth = createOutageMonthData(year, mn);
				dataset = createDataset(outagesByMonth);
			} else if (graphType.equals("3")) {
				graphOptions = "1";
				if (isNotNull(selectYear))
					yearSelected = " - " + selectYear;
				else{
					yearSelected = " - 2011";
					selectYear= "2011";
				}				
				projectKind = createProjectKindData(selectYear);
				dataset = createDataset(projectKind);
			}
			JFreeChart chart = createChart(dataset, icnService);
			chart.setBackgroundPaint(new Color(249, 231, 236));
			File uploadDir = new File(request.getSession().getServletContext()
					.getRealPath("/")
					+ "//");
			if (isNotNull(fileName)) {
				File file = new File(uploadDir, fileName);
				if (file.exists()) {
					file.delete();
				}
				final ChartRenderingInfo info = new ChartRenderingInfo(
						new StandardEntityCollection());
				ChartUtilities.saveChartAsPNG(file, chart, width, height, info);
				String mapTag = ChartUtilities
						.getImageMap(file.getPath(), info);
				session.setAttribute("maptag", mapTag);
				session.setAttribute("filename", file.getPath());
			} else {
				File file = new File(uploadDir, "graph.png");
				ChartUtilities.saveChartAsPNG(file, chart, 1000, 400,
						new ChartRenderingInfo());

			}
		} catch (Exception e) {
			e.printStackTrace();
			return "graph";
		}
		return "graph";
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public List<String> getYearList() {
		return yearList;
	}

	public void setYearList(List<String> yearList) {
		this.yearList = yearList;
	}

	public String getYearSelected() {
		return yearSelected;
	}

	public void setYearSelected(String yearSelected) {
		this.yearSelected = yearSelected;
	}

	public String getGraphType() {
		return graphType;
	}

	public void setGraphType(String graphType) {
		this.graphType = graphType;
	}

	public List<String> getMonthsList() {
		DateFormatSymbols dfs = new DateFormatSymbols();
		String[] months = dfs.getMonths();
		List<String> lst = new ArrayList<String>();
		lst.add("  ");
		for (int i = 0; i < months.length; i++) {
			if (isNotNull(months[i]))
				lst.add(months[i]);
		}
		return lst;
	}

	public void setMonthsList(List<String> monthsList) {
		this.monthsList = monthsList;
	}

	public int getMonth(String month) throws Exception {
		if (isNotNull(month)) {
			Date date = new SimpleDateFormat("MMM", Locale.ENGLISH)
					.parse(month);
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			return cal.get(Calendar.MONTH);
		}
		return -10;
	}

	public String getSelectYear() {
		return selectYear;
	}

	public void setSelectYear(String selectYear) {
		this.selectYear = selectYear;
	}

	public String getSelectMonth() {
		return selectMonth;
	}

	public void setSelectMonth(String selectMonth) {
		this.selectMonth = selectMonth;
	}

	public String getGraphOptions() {
		return graphOptions;
	}

	public void setGraphOptions(String graphOptions) {
		this.graphOptions = graphOptions;
	}
}